﻿using DevExpress.Data.Filtering;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Domain.Services;
using Volo.Abp.Uow;
using YAPACS.BusinessObjects.Exams;
using YAPACS.Organizations;
using YAPACS.RisServer.Abstractions;
using YAPACS.RisServer.Services.Dtos;
using YAPACS.RisServer.Workflows.Exams;
using YAPACS.Workflows;

namespace YAPACS.RisServer.Services;

public class ExamService(IUnitOfWorkManager unitOfWorkManager, IGetAdvancedSearchView getAdvancedSearchView, IExamListService examListService, IGetHeaders getHeaders, IAdvancedSearchExpression advancedSearchExpression, IGetDefaultFilter defaultFilter, IRepository<Institution, Guid> institutionRepository)
    : DomainService, IExamService, ITransientDependency
{
    private readonly IUnitOfWorkManager _unitOfWorkManager = unitOfWorkManager;
    private readonly IGetAdvancedSearchView _getAdvancedSearchView = getAdvancedSearchView;
    private readonly IExamListService _examListService = examListService;
    private readonly IGetHeaders _getHeaders = getHeaders;
    private readonly IAdvancedSearchExpression _advancedSearchExpression = advancedSearchExpression;
    private readonly IGetDefaultFilter _defaultFilter = defaultFilter;
    private readonly IRepository<Institution, Guid> _institutionRepository = institutionRepository;
    public async Task<WorkflowOutput> GetAdvancedSearchViewAsync()
    {
        try
        {
            var workflowOutput = await _getAdvancedSearchView.InvokeAsync([]);
            return workflowOutput;
        }
        catch (Exception ex)
        {
            Logger.LogException(ex);
            await _unitOfWorkManager.Current.RollbackAsync();
            return new WorkflowOutput
            {
                Success = false,
                Error = ex.Message
            };
        }
    }
    public async Task<WorkflowOutput> GetExamListByFilterAsync(DataGridRequest request, string institution, string applyDepartment, string applyDoctor)
    {
        try
        {
            CriteriaOperator criteriaOperator = CriteriaOperator.FromLambda<Exam>(e => e.ExamStatus == ExamStatus.Completed);
            if (string.IsNullOrWhiteSpace(institution))
            {
                institution = (await _institutionRepository.FirstOrDefaultAsync())?.Code;
            }
            if (!string.IsNullOrWhiteSpace(institution))
            {
                criteriaOperator = CriteriaOperator.And(criteriaOperator, CriteriaOperator.FromLambda<Exam>(e => e.Department != null && e.Department.Institution != null && institution == e.Department.Institution.Code));
            }
            if (!string.IsNullOrWhiteSpace(applyDepartment))
            {
                criteriaOperator = CriteriaOperator.And(criteriaOperator, CriteriaOperator.FromLambda<Exam>(e => e.ApplyDepartment != null && applyDepartment == e.ApplyDepartment.Code));
            }
            if (!string.IsNullOrWhiteSpace(applyDoctor))
            {
                criteriaOperator = CriteriaOperator.And(criteriaOperator, CriteriaOperator.FromLambda<Exam>(e => e.ApplyDoctor != null && applyDoctor == e.ApplyDoctor.Code));
            }
            var result = await _examListService.GetListByFilterAsync(request, criteriaOperator, _advancedSearchExpression, _getHeaders, getDefaultFilterWorkflow: _defaultFilter);
            return result;
        }
        catch (Exception ex)
        {
            Logger.LogException(ex);
            await _unitOfWorkManager.Current.RollbackAsync();
            return new WorkflowOutput()
            {
                Success = false,
                Error = ex.Message
            };
        }
    }
}
